package com.cdpm.web.service.impl;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.cdpm.common.core.domain.model.LoginUser;
import com.cdpm.common.utils.CollectionUtil;
import com.cdpm.common.utils.SecurityUtils;
import com.cdpm.common.utils.StringUtils;
import com.cdpm.common.utils.bean.BeanUtils;
import com.cdpm.system.domain.StrategyBuryingPoint;
import com.cdpm.system.domain.StrategyInstance;
import com.cdpm.system.domain.StrategyInstanceNode;
import com.cdpm.system.domain.TStrategyConfig;
import com.cdpm.system.service.IStrategyBuryingPointService;
import com.cdpm.system.service.IStrategyInstanceNodeService;
import com.cdpm.system.service.IStrategyInstanceService;
import com.cdpm.system.service.IStrategyService;
import com.cdpm.web.dto.*;
import com.cdpm.web.service.StrategyInfoService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @description:
 * @author: longjy
 * @create: 2024-09-04 14:34
 **/
@Service
public class StrategyInfoServiceImpl implements StrategyInfoService {

    @Resource
    IStrategyService iStrategyService;

    @Resource
    IStrategyInstanceService iStrategyInstanceService;

    @Resource
    IStrategyInstanceNodeService iStrategyInstanceNodeService;

    @Resource
    IStrategyBuryingPointService iStrategyBuryingPointService;
    /**
      * @Desctription：执行策略
      * @Author longjy
      * @Date 2024/9/4 14:42
      * @Param [strategyId]
      * @return
      */
    @Override
    public JSONObject executeStrategyById(Long strategyId) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("code","200");
        jsonObject.put("message","成功");
        try {
            TStrategyConfig tStrategyConfig = iStrategyService.findById(strategyId);
            //策略画布流程json
            String flowConfigTextStr = tStrategyConfig.getFlowConfigText();
            JSONObject flowConfigText = JSONObject.parseObject(flowConfigTextStr);
            //策略实例对象
            StrategyInstance strategyInstance = this.packageStrategyInstance(tStrategyConfig);
            strategyInstance.setStrategyId(tStrategyConfig.getStrategyId());
            List<StrategyInstanceNode> strategyInstanceNodeList = new ArrayList<>();
            JSONObject jsonObject1 = new JSONObject();
            jsonObject1.put("count",1);
            JSONObject nodeInfo = flowConfigText.getJSONObject("childNode");
            //递归策略节点集合
            this.recursionStrategyInstanceNode(strategyInstanceNodeList,nodeInfo,null,jsonObject1);
            //插入策略实例表
            iStrategyInstanceService.insert(strategyInstance);
            if(CollectionUtil.isNotEmpty(strategyInstanceNodeList)){
                LoginUser loginUser = SecurityUtils.getLoginUser();
                JSONObject statisticsNodeInfo = this.packageStatisticsNodeInfo();
                for (StrategyInstanceNode strategyInstanceNode : strategyInstanceNodeList) {
                    strategyInstanceNode.setStrategyInstanceId(strategyInstance.getStrategyInstanceId());
                    strategyInstanceNode.setStrategyId(tStrategyConfig.getStrategyId());
                    strategyInstanceNode.setInsertTime(new Date());
                    strategyInstanceNode.setInsertUser(loginUser.getUser().getUserName()+"");
                    strategyInstanceNode.setUpdateTime(new Date());
                    strategyInstanceNode.setUpdateUser(loginUser.getUser().getUserName()+"");
                    strategyInstanceNode.setIsDelete("0");
                    if(StringUtils.isNotEmpty(strategyInstanceNode.getNodeType()) && "2".equals(strategyInstanceNode.getNodeType())){
                        //内容节点
                        strategyInstanceNode.setExtraJson(statisticsNodeInfo.toString());
                    }else if(StringUtils.isNotEmpty(strategyInstanceNode.getNodeType()) && "1".equals(strategyInstanceNode.getNodeType())){
                        //目标节点
                        strategyInstanceNode.setExtraJson(this.packageStatisticsTargetNodeInfo().toString());
                    }

                    //插入策略实例节点表
                    iStrategyInstanceNodeService.insert(strategyInstanceNode);
                }
                //包装埋点集合
                List<StrategyBuryingPoint> strategyBuryingPoints = this.packageBuryingPoint(strategyInstanceNodeList);
                if(CollectionUtil.isNotEmpty(strategyBuryingPoints)){
                    for (StrategyBuryingPoint strategyBuryingPoint : strategyBuryingPoints) {
                        strategyBuryingPoint.setStrategyInstanceId(strategyInstance.getStrategyInstanceId());
                        strategyBuryingPoint.setInsertTime(new Date());
                        strategyBuryingPoint.setInsertUser(loginUser.getUser().getUserName()+"");
                        strategyBuryingPoint.setUpdateTime(new Date());
                        strategyBuryingPoint.setTargetCompletionRate("0");
                        strategyBuryingPoint.setCompleteCount("0");
                        strategyBuryingPoint.setTotalCount("0");
                        strategyBuryingPoint.setUpdateUser(loginUser.getUser().getUserName()+"");
                        strategyBuryingPoint.setIsDelete("0");
                        iStrategyBuryingPointService.insert(strategyBuryingPoint);
                    }
                }
            }
        }catch (Exception e){
            e.printStackTrace();
            jsonObject.put("code","500");
            jsonObject.put("message","失败");
        }
        return jsonObject;
    }

    public JSONObject packageStatisticsNodeInfo(){
        JSONObject jsonObject1 = new JSONObject();
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("总人数","0");
        jsonObject.put("报名人数","0");
        jsonObject.put("参与人数","0");
        jsonObject.put("完成活动","0");
        jsonObject.put("填写问卷","0");
        jsonObject1.put("statisticsNodeInfo",jsonObject);
        return jsonObject1;
    }

    public JSONObject packageStatisticsTargetNodeInfo(){
        JSONObject jsonObject1 = new JSONObject();
        jsonObject1.put("targetCompletionRate","0");
        return jsonObject1;
    }

    /**
      * @Desctription：查询目标节点和其父内容节点的统计信息
      * @Author longjy
      * @Date 2024/9/5 16:18
      * @Param [strategyInstanceId]
      * @return
      */
    @Override
    public List<StrategyTargetInfoDTO> queryStrategyTargetInfoDTO(Long strategyInstanceId) {
        StrategyInstanceNode strategyInstanceNode = new StrategyInstanceNode();
        List<StrategyTargetInfoDTO> strategyTargetInfoDTOS = new ArrayList<>();
        strategyInstanceNode.setStrategyInstanceId(strategyInstanceId);
        //查询该实例策略的所有节点
        List<StrategyInstanceNode> list = iStrategyInstanceNodeService.findList(strategyInstanceNode);
        if(CollectionUtil.isNotEmpty(list)){
            //筛选出目标节点
            List<StrategyInstanceNode> targetNodeList = this.getTargetNodeList(list);
            if(CollectionUtil.isNotEmpty(targetNodeList)){
                for (StrategyInstanceNode strategyInstanceNode1 : targetNodeList) {
                    StrategyTargetInfoDTO strategyTargetInfoDTO = new StrategyTargetInfoDTO();
                    strategyTargetInfoDTO.setNodeName(strategyInstanceNode1.getNodeName());
                    strategyTargetInfoDTO.setExtraJson(strategyInstanceNode1.getExtraJson());
                    //递归查询对应所有父内容节点
                    List<StrategyInstanceNodeDTO> strategyInstanceNodeDTOS = this.recursionStrategyInstanceNodeDTO(strategyInstanceNode1, list);
                    strategyTargetInfoDTO.setStrategyInstanceNodeDTOList(strategyInstanceNodeDTOS);
                    strategyTargetInfoDTOS.add(strategyTargetInfoDTO);
                }
            }
        }
        return strategyTargetInfoDTOS;
    }

    /**
      * @Desctription：递归查询对应所有父内容节点
      * @Author longjy
      * @Date 2024/9/5 15:45
      * @Param [strategyInstanceNode1, list]
      * @return
      */
    public List<StrategyInstanceNodeDTO> recursionStrategyInstanceNodeDTO(StrategyInstanceNode strategyInstanceNode1,List<StrategyInstanceNode> list){
        List<StrategyInstanceNodeDTO> strategyInstanceNodeDTOS = new ArrayList<>();
        List<StrategyInstanceNode> returnList = new ArrayList<>();
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("count",1);
        //递归查询所有父节点
        this.findParentNode(strategyInstanceNode1.getParentNodeId(), list, returnList,jsonObject);
        if(CollectionUtil.isNotEmpty(returnList)){
            //筛选出内容父节点
            for (StrategyInstanceNode strategyInstanceNode : returnList) {
                if("2".equals(strategyInstanceNode.getNodeType())){
                    StrategyInstanceNodeDTO strategyInstanceNodeDTO = new StrategyInstanceNodeDTO();
                    BeanUtils.copyBeanProp(strategyInstanceNodeDTO,strategyInstanceNode);
                    strategyInstanceNodeDTO.setStrategyInstanceId(strategyInstanceNode.getStrategyInstanceId()+"");
                    strategyInstanceNodeDTO.setStrategyId(strategyInstanceNode.getStrategyId()+"");
                    strategyInstanceNodeDTO.setNodeId(strategyInstanceNode.getNodeId()+"");
                    strategyInstanceNodeDTO.setParentNodeId(strategyInstanceNode.getParentNodeId()+"");
                    strategyInstanceNodeDTOS.add(strategyInstanceNodeDTO);
                }
            }
        }
        return strategyInstanceNodeDTOS;
    }

    /**
      * @Desctription：递归查询父节点
      * @Author longjy
      * @Date 2024/9/5 15:46
      * @Param [parentId, list, returnList]
      * @return
      */
    public void findParentNode(Long parentId,List<StrategyInstanceNode> list,List<StrategyInstanceNode> returnList,JSONObject jsonObject){
        Integer count = jsonObject.getInteger("count");
        if(count > 1000){
            //防止死递归
            return ;
        }
        jsonObject.put("count",++count);
        if(CollectionUtil.isNotEmpty(list)){
            for (StrategyInstanceNode strategyInstanceNode : list) {
                Long nodeId = strategyInstanceNode.getNodeId();
                if(parentId.equals(nodeId)){
                    returnList.add(strategyInstanceNode);
                    if(strategyInstanceNode.getParentNodeId() != null){
                        //递归查找父节点
                        this.findParentNode(strategyInstanceNode.getParentNodeId(),list,returnList,jsonObject);
                    }
                }
            }
        }
    }

    /**
      * @Desctription：筛选出目标节点
      * @Author longjy
      * @Date 2024/9/5 14:32
      * @Param [list]
      * @return
      */
    public List<StrategyInstanceNode> getTargetNodeList(List<StrategyInstanceNode> list){
        List<StrategyInstanceNode> targetInstanceNode = new ArrayList<>();
        for (StrategyInstanceNode instanceNode : list) {
            if("1".equals(instanceNode.getNodeType())){
                targetInstanceNode.add(instanceNode);
            }
        }
        return targetInstanceNode;
    }

    public List<StrategyBuryingPoint> packageBuryingPoint(List<StrategyInstanceNode> strategyInstanceNodeList){
        List<StrategyBuryingPoint> strategyBuryingPoints = new ArrayList<>();
        if(CollectionUtil.isNotEmpty(strategyInstanceNodeList)){
            for (StrategyInstanceNode strategyInstanceNode : strategyInstanceNodeList) {
                String nodeType = strategyInstanceNode.getNodeType();
                if("2".equals(nodeType)){
                    //节点的业务数据
                    List<StrategyBuryingPoint> buryingPoint = this.findBuryingPoint(strategyInstanceNode);
                    if(CollectionUtil.isNotEmpty(buryingPoint)){
                        strategyBuryingPoints.addAll(buryingPoint);
                    }
                }
            }
        }
        return strategyBuryingPoints;
    }

    /**
      * @Desctription：根据当前内容节点配置的业务数据匹配对应的埋点集合
      * @Author longjy
      * @Date 2024/9/6 15:08
      * @Param [strategyInstanceNode]
      * @return
      */
    public List<StrategyBuryingPoint> findBuryingPoint(StrategyInstanceNode strategyInstanceNode){
        String nodeDetail = strategyInstanceNode.getNodeDetail();
        List<StrategyBuryingPoint> strategyBuryingPoints = new ArrayList<>();
        if(StringUtils.isNotEmpty(nodeDetail)){
            JSONObject jsonObject = JSONObject.parseObject(nodeDetail);
            if(jsonObject!=null){
                String contentType = jsonObject.getString("contentType");
                if(StringUtils.isNotEmpty(contentType)){
                    List<EnumInfoDTO> enumList = new ArrayList<>();
                    if("onlineActivity".equals(contentType)){
                        enumList = ENUM_ONLINE_ACTIVITY_TYPE.getEnumList();
                    }else if("offlineActivity".equals(contentType)){
                        enumList = ENUM_OFFLINE_ACTIVITY_TYPE.getEnumList();
                    }else if("article".equals(contentType)){
                        enumList = ENUM_ACTIVITY_TYPE.getEnumList();
                    }else if("poster".equals(contentType)){
                        enumList = ENUM_POSTER_TYPE.getEnumList();
                    }
                    if(CollectionUtil.isNotEmpty(enumList)){
                        for (EnumInfoDTO enumInfoDTO : enumList) {
                            StrategyBuryingPoint strategyBuryingPoint = new StrategyBuryingPoint();
                            strategyBuryingPoint.setBuryingPointId(StringUtils.getId());
                            strategyBuryingPoint.setBuryingPointName(enumInfoDTO.getLabel());
                            strategyBuryingPoint.setBuryingPointType(enumInfoDTO.getValue());
                            strategyBuryingPoint.setNodeId(strategyInstanceNode.getNodeId());
                            strategyBuryingPoint.setNodeName(strategyInstanceNode.getNodeName());
                            strategyBuryingPoints.add(strategyBuryingPoint);
                        }
                    }
                }
            }
        }
        return strategyBuryingPoints;
    }

    public ENUM_BURYING_POINT_TYPE getBuryingEnum(){
        int i = StringUtils.generateRandomNumber(1);
        ENUM_BURYING_POINT_TYPE enum_burying_point_type = ENUM_BURYING_POINT_TYPE.NRLL;
        if(i<3){
            enum_burying_point_type = ENUM_BURYING_POINT_TYPE.HDBM;
        }else if(i>=3 && i<5){
            enum_burying_point_type = ENUM_BURYING_POINT_TYPE.HDCY;
        }else if(i>=5 && i<6){
            enum_burying_point_type = ENUM_BURYING_POINT_TYPE.NRLL;
        }else if(i>=6 && i<7){
            enum_burying_point_type = ENUM_BURYING_POINT_TYPE.TXWJ;
        }else if(i>=7 && i<11){
            enum_burying_point_type = ENUM_BURYING_POINT_TYPE.WCHD;
        }
        return enum_burying_point_type;
    }

    /**
      * @Desctription：递归策略节点集合
      * @Author longjy
      * @Date 2024/9/4 19:36
      * @Param [strategyInstanceNodeList, nodeInfo, parentNodeId]
      * @return
      */
    public List<StrategyInstanceNode> recursionStrategyInstanceNode(List<StrategyInstanceNode> strategyInstanceNodeList,JSONObject nodeInfo,Long parentNodeId,JSONObject jsonObject1){
        Integer count = jsonObject1.getInteger("count");
        if(count > 1000){
            //防止死递归
            return strategyInstanceNodeList;
        }
        jsonObject1.put("count",++count);
        StrategyInstanceNode strategyInstanceNode = new StrategyInstanceNode();
        strategyInstanceNode.setNodeId(StringUtils.getId());
        //节点名称
        String nodeName = nodeInfo.getString("nodeName");
        //节点id
        String id = nodeInfo.getString("id");
        //节点业务数据
        JSONObject nodeDetail = nodeInfo.getJSONObject("nodeDetail");
        //节点类型 目标：1，内容：2，客户分流：3，经营控制：6
        String type = nodeInfo.getString("type");
        strategyInstanceNode.setNodeName(nodeName);
        strategyInstanceNode.setOriginalNodeId(id);
        if(nodeDetail!=null){
            strategyInstanceNode.setNodeDetail(nodeDetail.toString());
        }
        strategyInstanceNode.setNodeType(type);
        if(parentNodeId != null){
            strategyInstanceNode.setParentNodeId(parentNodeId);
        }
        strategyInstanceNodeList.add(strategyInstanceNode);
        //子节点
        JSONObject childNode = nodeInfo.getJSONObject("childNode");
        if(childNode != null){
            JSONArray conditionNodes = childNode.getJSONArray("conditionNodes");
            if(conditionNodes != null && conditionNodes.size()>0){
                //是分流节点
                for(int i=0;i<conditionNodes.size();i++){
                    JSONObject jsonObject = conditionNodes.getJSONObject(i);
                    //递归子节点
                    this.recursionStrategyInstanceNode(strategyInstanceNodeList,jsonObject,strategyInstanceNode.getNodeId(),jsonObject1);
                }
            }else{
                //是单支节点
                String childNodeName = childNode.getString("nodeName");
                if(StringUtils.isNotEmpty(childNodeName)){
                    //递归子节点
                    this.recursionStrategyInstanceNode(strategyInstanceNodeList,childNode,strategyInstanceNode.getNodeId(),jsonObject1);
                }
            }
        }else{
            JSONArray conditionNodes2 = nodeInfo.getJSONArray("conditionNodes");
            if(conditionNodes2!=null && conditionNodes2.size()>0){
                //是分流节点
                for(int i=0;i<conditionNodes2.size();i++){
                    JSONObject jsonObject = conditionNodes2.getJSONObject(i);
                    //递归子节点
                    this.recursionStrategyInstanceNode(strategyInstanceNodeList,jsonObject,strategyInstanceNode.getNodeId(),jsonObject1);
                }
            }
        }
        return strategyInstanceNodeList;
    }

    /**
      * @Desctription：包装策略实例对象
      * @Author longjy
      * @Date 2024/9/4 16:17
      * @Param [tStrategyConfig]
      * @return
      */
    private StrategyInstance packageStrategyInstance(TStrategyConfig tStrategyConfig){
        LoginUser loginUser = SecurityUtils.getLoginUser();
        StrategyInstance strategyInstance = new StrategyInstance();
        strategyInstance.setStrategyInstanceId(new Date().getTime());
        BeanUtils.copyBeanProp(strategyInstance,tStrategyConfig);
        strategyInstance.setStrategyInstanceStatus(ENUM_STRATEGY_INSTANCE_STATUS_TYPE.ZXZ.getValue());
        strategyInstance.setInsertTime(new Date());
        strategyInstance.setInsertUser(loginUser.getUser().getUserName()+"");
        strategyInstance.setUpdateTime(new Date());
        strategyInstance.setUpdateUser(loginUser.getUser().getUserName()+"");
        strategyInstance.setIsDelete("0");
        strategyInstance.setTargetCompletionRate("0");
        strategyInstance.setCumulativeTriggering("0");
        strategyInstance.setAccumulatedEntry("0");
        strategyInstance.setGoalCompletion("0");
        return strategyInstance;
    }
}
